//
// Created by Ivor_ on 2023/2/4.
//

#include "fractal.h"

static double var1;
static double var2;
static double var3;
static double var4;

static void treeF_iter(STDbmp* bmpFile, int startPixelX, int startPixelY, int finalPixelX, int finalPixelY, int iterCount, PIXEL color);
static void sierpinskiTriangleF_iter(STDbmp* bmpFile, SCALE scale, int topPixelX, int topPixelY, int leftPixelX, int leftPixelY, int rightPixelX, int rightPixelY, int iterCount, PIXEL color);
static void kochF_iter(STDbmp* bmpFile, SCALE scale, int pixel1X, int pixel1Y, int pixel2X, int pixel2Y, int iterCount, PIXEL background, PIXEL color);
static void minkowskiSausageF_iter(STDbmp* bmpFile, int startPixelX, int startPixelY, int finalPixelX, int finalPixelY, int iterCount, PIXEL background, PIXEL color);
static double linearFunction2PF(double xx);

void treeF(char* fileName, int iterCount) {
    PIXEL whitePixel = {.red = 0xff, .green = 0xff, .blue = 0xff};
    PIXEL blackPixel = {.red = 0x0, .green = 0x0, .blue = 0x0};
    STDbmp* picture = bmpBO().new(fileName, 1920, 1080, whitePixel);
    bmpBO().drawRow(picture, 1920/2, 4, 1, blackPixel);
    treeF_iter(picture, 1920/2, 0, 1920/2, 1079, iterCount, blackPixel);
    bmpBO().close(picture);
}

void sierpinskiTriangleF(char* fileName, int iterCount) {
    PIXEL whitePixel = {.red = 0xff, .green = 0xff, .blue = 0xff};
    PIXEL blackPixel = {.red = 0x0, .green = 0x0, .blue = 0x0};
    SCALE scale = {.xStart = 0., .xEnd = 1919., .yStart = 0., .yEnd = 1079.};
    STDbmp* picture = bmpBO().new(fileName, 1920, 1080, whitePixel);
    var1 = 960.;
    var2 = 1079.;
    var3 = 327.462;
    var4 = 2.;
    bmpPlt().fun(picture, scale, linearFunction2PF, var1, var3, 4, 4, blackPixel);
    var1 = 327.462;
    var2 = 2.;
    var3 = 1592.538;
    var4 = 2.;
    bmpPlt().fun(picture, scale, linearFunction2PF, var1, var3, 4, 4, blackPixel);
    var1 = 1592.538;
    var2 = 2.;
    var3 = 960.;
    var4 = 1079.;
    bmpPlt().fun(picture, scale, linearFunction2PF, var1, var3, 4, 4, blackPixel);
    sierpinskiTriangleF_iter(picture, scale, 960, 1079, 327, 2, 1593, 2, iterCount, blackPixel);
    bmpBO().close(picture);
}

void kochSnowflakesF(char* fileName, int iterCount) {
    PIXEL whitePixel = {.red = 0xff, .green = 0xff, .blue = 0xff};
    PIXEL blackPixel = {.red = 0x0, .green = 0x0, .blue = 0x0};
    SCALE scale = {.xStart = 0., .xEnd = 1919., .yStart = 0., .yEnd = 1079.};
    STDbmp* picture = bmpBO().new(fileName, 1920, 1080, whitePixel);
    var1 = 657.;
    var2 = 15.;
    var3 = 1566.;
    var4 = 540.;
    bmpPlt().fun(picture, scale, linearFunction2PF, var1, var3, 4, 4, blackPixel);
    var1 = 1566.;
    var2 = 540.;
    var3 = 657.;
    var4 = 1065.;
    bmpPlt().fun(picture, scale, linearFunction2PF, var1, var3, 4, 4, blackPixel);
    bmpBO().drawRow(picture, 657, 4, 15, blackPixel);
    kochF_iter(picture, scale, 657, 15, 657, 1065, iterCount, whitePixel, blackPixel);
    kochF_iter(picture, scale, 657, 1065, 1566, 540, iterCount, whitePixel, blackPixel);
    kochF_iter(picture, scale, 1566, 540, 657, 15, iterCount, whitePixel, blackPixel);
    bmpBO().close(picture);
}

void kochCurveF(char* fileName1, char* fileName2, int iterCount) {
    PIXEL whitePixel = {.red = 0xff, .green = 0xff, .blue = 0xff};
    PIXEL blackPixel = {.red = 0x0, .green = 0x0, .blue = 0x0};
    SCALE scale = {.xStart = 0., .xEnd = 1919., .yStart = 0., .yEnd = 1079.};
    STDbmp* picture1 = bmpBO().new(fileName1, 1920, 1080, whitePixel);
    STDbmp* picture2 = bmpBO().new(fileName2, 1920, 1080, whitePixel);
    bmpBO().drawRow(picture1, 1536, 4, 15, blackPixel);
    kochF_iter(picture1, scale, 1536, 15, 1536, 1065, iterCount, whitePixel, blackPixel);
    bmpBO().close(picture1);
    bmpBO().drawLine(picture2, 216, 4, 15, blackPixel);
    kochF_iter(picture2, scale, 15, 216, 1905, 216, iterCount, whitePixel, blackPixel);
    bmpBO().close(picture2);
}

void minkowskiSausageF(char* fileName, int iterCount) {
    PIXEL whitePixel = {.red = 0xff, .green = 0xff, .blue = 0xff};
    PIXEL blackPixel = {.red = 0x0, .green = 0x0, .blue = 0x0};
    STDbmp* picture = bmpBO().new(fileName, 1920, 1080, whitePixel);
    bmpBO().drawLine(picture, 540, 4, 210, blackPixel);
    minkowskiSausageF_iter(picture, 210, 540, 1710, 540, iterCount, whitePixel, blackPixel);
    bmpBO().close(picture);
}

static void treeF_iter(STDbmp* bmpFile, int startPixelX, int startPixelY, int finalPixelX, int finalPixelY, int iterCount, PIXEL color) {
    if (iterCount > 0) {
        SCALE scale = {.xStart = 0., .xEnd = 1919., .yStart = 0., .yEnd = 1079.};
        double length = sqrt(0. + (finalPixelX - startPixelX)*(finalPixelX - startPixelX) + (finalPixelY - startPixelY)*(finalPixelY - startPixelY));
        double theta = atan(1. * (finalPixelY-startPixelY) / (finalPixelX-startPixelX));
        if (theta < 0.) {
            theta += M_PI;
        }
        int trisectionPointPixel1X = (int)((2.*startPixelX + 1.*finalPixelX) / 3.);
        int trisectionPointPixel1Y = (int)((2.*startPixelY + 1.*finalPixelY) / 3.);
        int trisectionPointPixel2X = (int)((1.*startPixelX + 2.*finalPixelX) / 3.);
        int trisectionPointPixel2Y = (int)((1.*startPixelY + 2.*finalPixelY) / 3.);
        int objPixel1X = (int)((2. * startPixelX + 1. * finalPixelX)/3. + length/3.*cos(theta + M_PI/6.));
        int objPixel1Y = (int)((2. * startPixelY + 1. * finalPixelY)/3. + length/3.*sin(theta + M_PI/6.));
        int objPixel2X = (int)((1. * startPixelX + 2. * finalPixelX)/3. + length/3.*cos(theta - M_PI/6.));
        int objPixel2Y = (int)((1. * startPixelY + 2. * finalPixelY)/3. + length/3.*sin(theta - M_PI/6.));
        var1 = 1. * trisectionPointPixel1X;
        var2 = 1. * trisectionPointPixel1Y;
        var3 = 1. * objPixel1X;
        var4 = 1. * objPixel1Y;
        if (fabs(var1 - var3) < 3.) {
            for (int i = (trisectionPointPixel1Y > objPixel1Y ? objPixel1Y : trisectionPointPixel1Y); i <= (trisectionPointPixel1Y < objPixel1Y ? objPixel1Y : trisectionPointPixel1Y); ++i) {
                bmpBO().drawPoint(bmpFile, trisectionPointPixel1X, i, 4, 4, color);
            }
        } else {
            bmpPlt().fun(bmpFile, scale, linearFunction2PF, var1, var3, 4, 4, color);
        }
        var1 = 1. * trisectionPointPixel2X;
        var2 = 1. * trisectionPointPixel2Y;
        var3 = 1. * objPixel2X;
        var4 = 1. * objPixel2Y;
        if (fabs(var1 - var3) < 3.) {
            for (int i = (trisectionPointPixel2Y > objPixel2Y ? objPixel2Y : trisectionPointPixel2Y); i <= (trisectionPointPixel2Y < objPixel2Y ? objPixel2Y : trisectionPointPixel2Y); ++i) {
                bmpBO().drawPoint(bmpFile, trisectionPointPixel2X, i, 4, 4, color);
            }
        } else {
            bmpPlt().fun(bmpFile, scale, linearFunction2PF, var1, var3, 4, 4, color);
        }
        iterCount--;
        treeF_iter(bmpFile, startPixelX, startPixelY, trisectionPointPixel1X, trisectionPointPixel1Y, iterCount, color);
        treeF_iter(bmpFile, trisectionPointPixel1X, trisectionPointPixel1Y, objPixel1X, objPixel1Y, iterCount, color);
        treeF_iter(bmpFile, trisectionPointPixel1X, trisectionPointPixel1Y, trisectionPointPixel2X, trisectionPointPixel2Y, iterCount, color);
        treeF_iter(bmpFile, trisectionPointPixel2X, trisectionPointPixel2Y, objPixel2X, objPixel2Y, iterCount, color);
        treeF_iter(bmpFile, trisectionPointPixel2X, trisectionPointPixel2Y, finalPixelX, finalPixelY, iterCount, color);
    }
    return;
}

static void sierpinskiTriangleF_iter(STDbmp* bmpFile, SCALE scale, int topPixelX, int topPixelY, int leftPixelX, int leftPixelY, int rightPixelX, int rightPixelY, int iterCount, PIXEL color) {
    if (iterCount > 0) {
        int midPointLeftPixelX = (int)((topPixelX+leftPixelX) / 2.);
        int midPointLeftPixelY = (int)((topPixelY+leftPixelY) / 2.);
        int midPointRightPixelX = (int)((topPixelX+rightPixelX) / 2.);
        int midPointRightPixelY = (int)((topPixelY+rightPixelY) / 2.);
        int midPointBottomPixelX = (int)((leftPixelX+rightPixelX) / 2.);
        int midPointBottomPixelY = (int)((leftPixelY+rightPixelY) / 2.);
        var1 = 1.* midPointLeftPixelX;
        var2 = 1.* midPointLeftPixelY;
        var3 = 1.* midPointRightPixelX;
        var4 = 1.* midPointRightPixelY;
        bmpPlt().fun(bmpFile, scale, linearFunction2PF, var1, var3, 4, 4, color);
        var1 = 1.* midPointRightPixelX;
        var2 = 1.* midPointRightPixelY;
        var3 = 1.* midPointBottomPixelX;
        var4 = 1.* midPointBottomPixelY;
        bmpPlt().fun(bmpFile, scale, linearFunction2PF, var1, var3, 4, 4, color);
        var1 = 1.* midPointBottomPixelX;
        var2 = 1.* midPointBottomPixelY;
        var3 = 1.* midPointLeftPixelX;
        var4 = 1.* midPointLeftPixelY;
        bmpPlt().fun(bmpFile, scale, linearFunction2PF, var1, var3, 4, 4, color);
        iterCount--;
        sierpinskiTriangleF_iter(bmpFile, scale, topPixelX, topPixelY, midPointLeftPixelX, midPointLeftPixelY, midPointRightPixelX, midPointRightPixelY, iterCount, color);
        sierpinskiTriangleF_iter(bmpFile, scale, midPointLeftPixelX, midPointLeftPixelY, leftPixelX, leftPixelY, midPointBottomPixelX, midPointBottomPixelY, iterCount, color);
        sierpinskiTriangleF_iter(bmpFile, scale, midPointRightPixelX, midPointRightPixelY, midPointBottomPixelX, midPointBottomPixelY, rightPixelX, rightPixelY, iterCount, color);
    }
    return;
}

static void kochF_iter(STDbmp* bmpFile, SCALE scale, int pixel1X, int pixel1Y, int pixel2X, int pixel2Y, int iterCount, PIXEL background, PIXEL color) {
    if (iterCount > 0) {
        double length = sqrt(0. + (pixel2X - pixel1X)*(pixel2X - pixel1X) + (pixel2Y- pixel1Y)*(pixel2Y - pixel1Y));
        double theta = atan(1. * (pixel2Y-pixel1Y) / (pixel2X-pixel1X));
        if ((pixel2X-pixel1X) < 0) {
            theta += (theta / fabs(theta) *M_PI);
        }
        int trisectionPointPixel1X = (int)((2.*pixel1X + 1.*pixel2X) / 3.);
        int trisectionPointPixel1Y = (int)((2.*pixel1Y + 1.*pixel2Y) / 3.);
        int trisectionPointPixel2X = (int)((1.*pixel1X + 2.*pixel2X) / 3.);
        int trisectionPointPixel2Y = (int)((1.*pixel1Y + 2.*pixel2Y) / 3.);
        int objPixelX = (int)((2. * pixel1X + 1. * pixel2X)/3. + length/3.*cos(theta + M_PI/3.));
        int objPixelY = (int)((2. * pixel1Y + 1. * pixel2Y)/3. + length/3.*sin(theta + M_PI/3.));
        var1 = 1. * trisectionPointPixel1X;
        var2 = 1. * trisectionPointPixel1Y;
        var3 = 1. * trisectionPointPixel2X;
        var4 = 1. * trisectionPointPixel2Y;
        if (fabs(var1 - var3) < 3.) {
            for (int i = (trisectionPointPixel1Y > trisectionPointPixel2Y ? trisectionPointPixel2Y : trisectionPointPixel1Y); i <= (trisectionPointPixel1Y < trisectionPointPixel2Y ? trisectionPointPixel2Y : trisectionPointPixel1Y); ++i) {
                bmpBO().drawPoint(bmpFile, trisectionPointPixel1X, i, 6, 6, background);
            }
        } else {
            bmpPlt().fun(bmpFile, scale, linearFunction2PF, var1, var3, 6, 6, background);
        }
        var1 = 1. * trisectionPointPixel1X;
        var2 = 1. * trisectionPointPixel1Y;
        var3 = 1. * objPixelX;
        var4 = 1. * objPixelY;
        if (fabs(var1 - var3) < 3.) {
            for (int i = (trisectionPointPixel1Y > objPixelY ? objPixelY : trisectionPointPixel1Y); i <= (trisectionPointPixel1Y < objPixelY ? objPixelY : trisectionPointPixel1Y); ++i) {
                bmpBO().drawPoint(bmpFile, trisectionPointPixel1X, i, 4, 4, color);
            }
        } else {
            bmpPlt().fun(bmpFile, scale, linearFunction2PF, var1, var3, 4, 4, color);
        }
        var1 = 1. * objPixelX;
        var2 = 1. * objPixelY;
        var3 = 1. * trisectionPointPixel2X;
        var4 = 1. * trisectionPointPixel2Y;
        if (fabs(var1 - var3) < 3.) {
            for (int i = (objPixelY > trisectionPointPixel2Y ? trisectionPointPixel2Y : objPixelY); i <= (objPixelY < trisectionPointPixel2Y ? trisectionPointPixel2Y : objPixelY); ++i) {
                bmpBO().drawPoint(bmpFile, objPixelX, i, 4, 4, color);
            }
        } else {
            bmpPlt().fun(bmpFile, scale, linearFunction2PF, var1, var3, 4, 4, color);
        }
        iterCount--;
        kochF_iter(bmpFile, scale, pixel1X, pixel1Y, trisectionPointPixel1X, trisectionPointPixel1Y, iterCount,
                   background, color);
        kochF_iter(bmpFile, scale, trisectionPointPixel1X, trisectionPointPixel1Y, objPixelX, objPixelY, iterCount,
                   background, color);
        kochF_iter(bmpFile, scale, objPixelX, objPixelY, trisectionPointPixel2X, trisectionPointPixel2Y, iterCount,
                   background, color);
        kochF_iter(bmpFile, scale, trisectionPointPixel2X, trisectionPointPixel2Y, pixel2X, pixel2Y, iterCount,
                   background, color);
    }
    return;
}

static void minkowskiSausageF_iter(STDbmp* bmpFile, int startPixelX, int startPixelY, int finalPixelX, int finalPixelY, int iterCount, PIXEL background, PIXEL color) {
    if (iterCount > 0) {
        if (startPixelX < finalPixelX) {
            int pixel1X = (int)(3.*startPixelX/4. + finalPixelX/4.);
            int pixel2X = (int)(startPixelX/2. + finalPixelX/2.);
            int pixel3X = (int)(startPixelX/4. + 3.*finalPixelX/4.);
            int len = pixel2X - pixel1X;
            for (int i = pixel1X; i <= pixel3X; ++i) {
                bmpBO().drawPoint(bmpFile, i, startPixelY, 4, 4, background);
            }
            for (int i = startPixelY; i <= startPixelY+len; ++i) {
                bmpBO().drawPoint(bmpFile, pixel1X, i, 4, 4, color);
            }
            for (int i = pixel1X; i <= pixel2X; ++i) {
                bmpBO().drawPoint(bmpFile, i, startPixelY+len, 4, 4, color);
            }
            for (int i = startPixelY+len; i >= finalPixelY-len; --i) {
                bmpBO().drawPoint(bmpFile, pixel2X, i, 4, 4, color);
            }
            for (int i = pixel2X; i <= pixel3X; ++i) {
                bmpBO().drawPoint(bmpFile, i, startPixelY-len, 4, 4, color);
            }
            for (int i = finalPixelY-len; i <= finalPixelY; ++i) {
                bmpBO().drawPoint(bmpFile, pixel3X, i, 4, 4, color);
            }
            iterCount--;
            minkowskiSausageF_iter(bmpFile, startPixelX, startPixelY, pixel1X, startPixelY, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel1X, startPixelY, pixel1X, startPixelY+len, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel1X, startPixelY+len, pixel2X, startPixelY+len, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel2X, startPixelY+len, pixel2X, finalPixelY, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel2X, finalPixelY, pixel2X, finalPixelY-len, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel2X, finalPixelY-len, pixel3X, finalPixelY-len, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel3X, finalPixelY-len, pixel3X, finalPixelY, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel3X, finalPixelY, finalPixelX, finalPixelY, iterCount, background, color);
        } else if (startPixelX > finalPixelX) {
            int pixel1X = (int)(3.*startPixelX/4. + finalPixelX/4.);
            int pixel2X = (int)(startPixelX/2. + finalPixelX/2.);
            int pixel3X = (int)(startPixelX/4. + 3.*finalPixelX/4.);
            int len = pixel1X - pixel2X;
            for (int i = pixel1X; i >= pixel3X; --i) {
                bmpBO().drawPoint(bmpFile, i, startPixelY, 4, 4, background);
            }
            for (int i = startPixelY; i >= startPixelY-len; --i) {
                bmpBO().drawPoint(bmpFile, pixel1X, i, 4, 4, color);
            }
            for (int i = pixel1X; i >= pixel2X; --i) {
                bmpBO().drawPoint(bmpFile, i, startPixelY-len, 4, 4, color);
            }
            for (int i = startPixelY-len; i <= finalPixelY+len; ++i) {
                bmpBO().drawPoint(bmpFile, pixel2X, i, 4, 4, color);
            }
            for (int i = pixel2X; i >= pixel3X; --i) {
                bmpBO().drawPoint(bmpFile, i, startPixelY+len, 4, 4, color);
            }
            for (int i = finalPixelY+len; i >= finalPixelY; --i) {
                bmpBO().drawPoint(bmpFile, pixel3X, i, 4, 4, color);
            }
            iterCount--;
            minkowskiSausageF_iter(bmpFile, startPixelX, startPixelY, pixel1X, startPixelY, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel1X, startPixelY, pixel1X, startPixelY-len, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel1X, startPixelY-len, pixel2X, startPixelY-len, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel2X, startPixelY-len, pixel2X, finalPixelY, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel2X, finalPixelY, pixel2X, finalPixelY+len, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel2X, finalPixelY+len, pixel3X, finalPixelY+len, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel3X, finalPixelY+len, pixel3X, finalPixelY, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, pixel3X, finalPixelY, finalPixelX, finalPixelY, iterCount, background, color);
        } else if (startPixelY < finalPixelY) {
            int pixel1Y = (int)(3.*startPixelY/4. + finalPixelY/4.);
            int pixel2Y = (int)(startPixelY/2. + finalPixelY/2.);
            int pixel3Y = (int)(startPixelY/4. + 3.*finalPixelY/4.);
            int len = pixel2Y - pixel1Y;
            for (int i = pixel1Y; i <= pixel3Y; ++i) {
                bmpBO().drawPoint(bmpFile, startPixelX, i, 4, 4, background);
            }
            for (int i = startPixelX; i >= startPixelX-len; --i) {
                bmpBO().drawPoint(bmpFile, i, pixel1Y, 4, 4, color);
            }
            for (int i = pixel1Y; i <= pixel2Y; ++i) {
                bmpBO().drawPoint(bmpFile, startPixelX-len, i, 4, 4, color);
            }
            for (int i = startPixelX-len; i <= finalPixelX+len; ++i) {
                bmpBO().drawPoint(bmpFile, i, pixel2Y, 4, 4, color);
            }
            for (int i = pixel2Y; i <= pixel3Y; ++i) {
                bmpBO().drawPoint(bmpFile, startPixelX+len, i, 4, 4, color);
            }
            for (int i = finalPixelX+len; i >= finalPixelX; --i) {
                bmpBO().drawPoint(bmpFile, i, pixel3Y, 4, 4, color);
            }
            iterCount--;
            minkowskiSausageF_iter(bmpFile, startPixelX, startPixelY, startPixelX, pixel1Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, startPixelX, pixel1Y, startPixelX-len, pixel1Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, startPixelX-len, pixel1Y, startPixelX-len, pixel2Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, startPixelX-len, pixel2Y, finalPixelX, pixel2Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, finalPixelX, pixel2Y, finalPixelX+len, pixel2Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, finalPixelX+len, pixel2Y, finalPixelX+len, pixel3Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, finalPixelX+len, pixel3Y, finalPixelX, pixel3Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, finalPixelX, pixel3Y, finalPixelX, finalPixelY, iterCount, background, color);
        } else if (startPixelY > finalPixelY) {
            int pixel1Y = (int)(3.*startPixelY/4. + finalPixelY/4.);
            int pixel2Y = (int)(startPixelY/2. + finalPixelY/2.);
            int pixel3Y = (int)(startPixelY/4. + 3.*finalPixelY/4.);
            int len = pixel1Y - pixel2Y;
            for (int i = pixel1Y; i >= pixel3Y; --i) {
                bmpBO().drawPoint(bmpFile, startPixelX, i, 4, 4, background);
            }
            for (int i = startPixelX; i <= startPixelX+len; ++i) {
                bmpBO().drawPoint(bmpFile, i, pixel1Y, 4, 4, color);
            }
            for (int i = pixel1Y; i >= pixel2Y; --i) {
                bmpBO().drawPoint(bmpFile, startPixelX+len, i, 4, 4, color);
            }
            for (int i = startPixelX+len; i >= finalPixelX-len; --i) {
                bmpBO().drawPoint(bmpFile, i, pixel2Y, 4, 4, color);
            }
            for (int i = pixel2Y; i >= pixel3Y; --i) {
                bmpBO().drawPoint(bmpFile, startPixelX-len, i, 4, 4, color);
            }
            for (int i = finalPixelX-len; i <= finalPixelX; ++i) {
                bmpBO().drawPoint(bmpFile, i, pixel3Y, 4, 4, color);
            }
            iterCount--;
            minkowskiSausageF_iter(bmpFile, startPixelX, startPixelY, startPixelX, pixel1Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, startPixelX, pixel1Y, startPixelX+len, pixel1Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, startPixelX+len, pixel1Y, startPixelX+len, pixel2Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, startPixelX+len, pixel2Y, finalPixelX, pixel2Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, finalPixelX, pixel2Y, finalPixelX-len, pixel2Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, finalPixelX-len, pixel2Y, finalPixelX-len, pixel3Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, finalPixelX-len, pixel3Y, finalPixelX, pixel3Y, iterCount, background, color);
            minkowskiSausageF_iter(bmpFile, finalPixelX, pixel3Y, finalPixelX, finalPixelY, iterCount, background, color);
        }
    }
    return;
}

static double linearFunction2PF(double xx) {
    return (xx - var3)/(var1 - var3)*var2 + (xx - var1)/(var3 - var1)*var4;
}
